package com.laikan.library.httpvolley.helper;

import android.content.Context;
import com.laikan.library.utils.DeviceUtil;

import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.util.*;

public class SecurityHelper {

    public static final Charset DEFAULT_CHARSET;
    private static final char[] DIGITS_LOWER;
    private static final char[] DIGITS_UPPER;

    static {
        DEFAULT_CHARSET = Charset.forName("UTF-8");
        DIGITS_LOWER = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
        DIGITS_UPPER = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
    }

    public static void sign(Context context, Map<String, String> params) {
        if (context != null && params != null) {
            params.putAll(getBaseParams(context));
            String[] keys = params.keySet().toArray(new String[0]);
            Arrays.sort(keys);
            ArrayList<String> signPair = new ArrayList<String>();
            for (String key : keys) {
                signPair.add(key + "=" + params.get(key));
            }
            String signContent = getSignResult(signPair, "&") + GlobalConfiguration.AUTH_APP_SECRET;
            MessageDigest messageDigest;
            try {
                messageDigest = MessageDigest.getInstance("MD5");
                messageDigest.reset();
                messageDigest.update(signContent.getBytes("UTF8"));
                final byte[] resultByte = messageDigest.digest();
                final String result = new String(encodeHex(resultByte));
                //添加签名
                params.put(GlobalConfiguration.PARAMES_APP_SIGN, result);

            }catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    //    public static void signMultPart(Context context, Map<String, String> params, RequestParams requestParams) {
    //        if(context != null && params != null) {
    //            params.putAll(getBaseParams(context));
    //            String[] keys = params.keySet().toArray(new String[0]);
    //            Arrays.sort(keys);
    //            ArrayList<String> signPair = new ArrayList<String>();
    //            for(String key : keys) {
    //                signPair.add(key + "=" + params.get(key));
    //                requestParams.addBodyParameter(key, params.get(key));
    //            }
    //            String signContent = getSignResult(signPair, "&") + GlobalConfiguration.AUTH_APP_SECRET;
    //            MessageDigest messageDigest;
    //            try {
    //                messageDigest = MessageDigest.getInstance("MD5");
    //                messageDigest.reset();
    //                messageDigest.update(signContent.getBytes("UTF8"));
    //                final byte[] resultByte = messageDigest.digest();
    //                final String result = new String(encodeHex(resultByte));
    //                //添加签名
    //                requestParams.addBodyParameter(GlobalConfiguration.PARAMES_APP_SIGN, result);
    //            }catch(Exception e) {
    //                e.printStackTrace();
    //            }
    //        }
    //    }

    private static Map<String, String> getBaseParams(Context context) {
        Map<String, String> params = new HashMap<>();
        params.put(GlobalConfiguration.TOKEN_API_KEY, GlobalConfiguration.AUTH_APP_KEY);
        params.put(GlobalConfiguration.PARAMES_CHANNEL_TYPE, "2");
        params.put(GlobalConfiguration.PARAMES_OS, GlobalConfiguration.TOKEN_OS_VALUE);
        params.put(GlobalConfiguration.PARAMES_CHANNEL, "");
        String channel = DeviceUtil.getMetaDataStringValue(context, "UMENG_CHANNEL");
        if (channel != null) {
            params.put(GlobalConfiguration.PARAMES_CHANNEL, channel);
        }
        return params;
    }

    public static String getSignResult(Iterable<?> iterable, String separator) {
        return iterable == null ? null : sign(iterable.iterator(), separator);
    }

    public static String sign(Iterator<?> iterator, String separator) {
        if (iterator == null) {
            return null;
        }else if (!iterator.hasNext()) {
            return "";
        }else {
            Object first = iterator.next();
            if (!iterator.hasNext()) {
                String buf1 = toString(first);
                return buf1;
            }else {
                StringBuilder buf = new StringBuilder(256);
                if (first != null) {
                    buf.append(first);
                }

                while (iterator.hasNext()) {
                    if (separator != null) {
                        buf.append(separator);
                    }

                    Object obj = iterator.next();
                    if (obj != null) {
                        buf.append(obj);
                    }
                }

                return buf.toString();
            }
        }
    }

    public static String toString(Object obj) {
        return obj == null ? "" : obj.toString();
    }

    public static char[] encodeHex(byte[] data) {
        return encodeHex(data, true);
    }

    public static char[] encodeHex(byte[] data, boolean toLowerCase) {
        return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
    }

    protected static char[] encodeHex(byte[] data, char[] toDigits) {
        int l = data.length;
        char[] out = new char[l << 1];
        int i = 0;

        for (int j = 0; i < l; ++i) {
            out[j++] = toDigits[(240 & data[i]) >>> 4];
            out[j++] = toDigits[15 & data[i]];
        }

        return out;
    }

}
